home *** CD-ROM | disk | FTP | other *** search
- //
- #import <math.h>
- #include <sys/stat.h>
-
- #import "Background.h"
-
- #import <dpsclient/wraps.h>
- #import <appkit/Application.h>
- #import <objc/hashtable.h>
- #import <defaults/defaults.h>
- #import "PSsplat.h"
- #import <appkit/OpenPanel.h>
- #import <appkit/Control.h>
- #import <appkit/Menu.h>
- #import <appkit/MenuCell.h>
- #import <appkit/Matrix.h>
- #import <appkit/nextstd.h>
-
- #define PSsplat( r, p) _PSsplat( (r)->origin.x, (r)->origin.y, \
- (r)->size.width, (r)->size.height, (p)->x, (p)->y)
-
- //
- @implementation Background:View
- //
- //
- void handler(DPSTimedEntry teNumber, double now, id background)
- {
- [background next:nil];
- }
-
- - initFrame:(const NXRect *)frameRect
- {
- char *d,*f;
- int len;
-
- [super initFrame:frameRect];
- imageNames = NULL;
- imageTimes = NULL;
- images = NULL;
- imageCount = 0;
- max = 0;
- current = 0;
- d = getenv("HOME"); if (!d) d="";
- f = ".background";
- len = strlen(d) + 1 + strlen(f) + 1;
- defaultfile = NX_ZONEMALLOC([self zone], defaultfile, char, len);
- strcpy(defaultfile, d);
- strcat(defaultfile,"/");
- strcat(defaultfile,f);
- timer = NULL;
- repeat = 600;
- permanent = NO;
- updateMenu = YES;
- return self;
- }
-
-
-
- - reset
- {
- int i;
-
- for (i=0; i<imageCount; i++) {
- NXZoneFree([self zone], imageNames[i]);
- if(images[i]) [images[i] free];
- }
- if (imageCount) {
- NXZoneFree([self zone], imageNames);
- NXZoneFree([self zone], imageTimes);
- NXZoneFree([self zone], images);
- }
- imageCount=0;
- current=0;
- return self;
- }
-
- - free
- {
- [self reset];
- if (timer) DPSRemoveTimedEntry(timer);
- return [super free];
- }
-
- //
- - loadImageNamed:(const char *)aName
- {
- // printf("Loading %s.\n", aName);
- if ([self getImage:aName]<0) return nil;
- return self;
- }
-
- - setImageNamed:(const char *)aName
- {
- int i;
-
- i = [self getImage:aName];
- if (i>=0) [self setImage:i]; else return nil;
- return self;
- }
-
- - setRepeatValue:(float)r
- {
- char str[7];
-
- repeat = r;
- if (timer) DPSRemoveTimedEntry(timer);
- if (repeat<1) {
- strcpy(str,"off");
- timer=NULL;
- } else {
- if (r<60) sprintf(str,"%2ds",(int)r);
- else if (r<3600) sprintf(str,"%2dmin",(int)(r/60));
- else sprintf(str,"%2dh",(int)(r/3600));
- timer = DPSAddTimedEntry(repeat,
- (DPSTimedEntryProc)handler, self, NX_BASETHRESHOLD);
- }
- [repeatText setStringValue:str];
- [repeatSlider setFloatValue:log(r+1)/12];
- // printf("Setting repeat to %s.\n", str);
- [self writeDefault];
- return self;
- }
-
- - setRepeatText:aText
- {
- repeatText = aText;
- return self;
- }
-
- - setRepeatSlider:aSlider
- {
- repeatSlider = aSlider;
- return self;
- }
-
- - setPermanent:(BOOL)flag
- {
- permanent = flag;
- return self;
- }
- //
- // target/action
- //
- - open:sender
- {
- OpenPanel *op=[OpenPanel new];
- char *types[]={ "tiff", "eps", NULL};
- char *directory, *filename, *fn;
- const char *d;
- const char * const *files;
- int l, len, ind;
-
- if( !imageCount)
- {
- directory=getenv( "HOME");
- if( !directory) directory="/";
- filename=NXCopyStringBufferFromZone("", [self zone]);
- } else {
- fn=NXCopyStringBufferFromZone(imageNames[current], [self zone]);
- if (filename=rindex(fn, '/')) *filename++='\0', directory=fn;
- else
- {
- filename=imageNames[current];
- directory=getenv( "HOME");
- if( !directory) directory="/";
- }
- }
- ind = current;
- [op allowMultipleFiles:YES];
- if( [op runModalForDirectory:directory file:filename types:types]) {
- len = 0;
- for (files=[op filenames]; *files; files++) if ((l=strlen(*files))>len) len=l;
- len += strlen(d=[op directory])+2;
- NX_ZONEMALLOC([self zone], fn, char, len);
- strcpy(fn,d);
- strcat(fn,"/");
- filename=rindex(fn, '/')+1;
- for (files=[op filenames]; *files; files++) {
- strcpy(filename,*files);
- if ((l=[self getImage:fn])>0) ind = l;
- }
- }
- [self setImage:ind];
- [self writeDefault];
- return self;
- }
-
- - next:sender
- {
- if (++current>=imageCount) current=0;
- [self setImage:current];
- return self;
- }
-
- - resize:sender
- {
- char *p;
-
- p = imageNames[current];
- if (p[0]=='*') {
- NX_ZONEMALLOC([self zone], imageNames[current], char, strlen(p));
- strcpy(imageNames[current], p+1);
- NXZoneFree([self zone], p);
- [images[current] free];
- images[current]=nil;
- } else {
- NX_ZONEMALLOC([self zone], imageNames[current], char, strlen(p)+2);
- strcpy(imageNames[current],"*");
- strcat(imageNames[current],p);
- NXZoneFree([self zone], p);
- }
- [self resizeImage:current];
- [self setImage:current];
- [self writeDefault];
- return self;
- }
-
- - previous:sender
- {
- if (--current<0) current=imageCount-1;
- [self setImage:current];
- return self;
- }
-
- - redraw:sender
- {
- [self display];
- return self;
- }
- - select:sender
- {
- sender = [sender selectedCell];
- updateMenu=NO;
- [self setImageNamed:[sender title]];
- updateMenu=YES;
- return self;
- }
- - toFront:sender
- {
- PSsetwindowlevel( NX_DOCKLEVEL+1, [window windowNum]);
- [window orderFront:sender];
- [window addToEventMask:NX_MOUSEDOWNMASK];
- return self;
- }
- - toTop:sender
- {
- int i;
- char *n;
- time_t t;
- id img;
-
- n = imageNames[current];
- t = imageTimes[current];
- img = images[current];
- for (i=current; i>0; i--) {
- imageNames[i] = imageNames[i-1];
- imageTimes[i] = imageTimes[i-1];
- images[i] = images[i-1];
- }
- imageNames[0] = n;
- imageTimes[0] = t;
- images[0] = img;
- current = 0;
- [self setImage:current];
- [self writeDefault];
- return self;
- }
-
- - delete:sender
- {
- int i;
-
- for (i=current; i<imageCount; i++) {
- imageNames[i] = imageNames[i+1];
- imageTimes[i] = imageTimes[i+1];
- images[i] = images[i+1];
- }
- imageCount--;
- if (current>=imageCount && current>0) current--;
- [self setImage:current];
- [self writeDefault];
- return self;
- }
-
- - deleteAll:sender
- {
- [self reset];
- [self setImage:current];
- return self;
- }
-
- - takeRepeatValueFrom:sender
- {
- [self setRepeatValue:exp(12*[sender floatValue])-1];
- return self;
- }
-
-
- ///
- /// Menu generation
- ///
- - setMenu:aMenuCell
- {
- menu = [aMenuCell target];
- [self updateMenu];
- return self;
- }
-
- - updateMenu
- {
- id cell;
- id matrix;
- int i;
-
- if (!updateMenu) return self;
- matrix = [menu itemList];
- while([matrix cellCount]) [matrix removeRowAt:0 andFree:YES];
- [menu setItemList:matrix];
- for (i=0; i<imageCount; i++) {
- cell = [menu addItem:imageNames[i] action:@selector(select:) keyEquivalent:0];
- [cell setTarget:self];
- }
- [menu display];
- return self;
- }
- //
- // private:
- //
- - (int)getImage:(const char *)aName
- {
- int i;
-
- if (aName==NULL) return -1;
- for (i=0; i<imageCount; i++) if (strcmp(aName, imageNames[i])==0) break;
- if (i>=imageCount) {
- if (++imageCount>max) {
- if (!max) {
- imageNames = NX_ZONEMALLOC([self zone], imageNames, char *, 1);
- imageTimes = NX_ZONEMALLOC([self zone], imageTimes, time_t, 1);
- images = NX_ZONEMALLOC([self zone], images, NXImage *, 1);
- max = 1;
- } else {
- max *= 2;
- imageNames = NX_ZONEREALLOC([self zone], imageNames, char *, max);
- imageTimes = NX_ZONEREALLOC([self zone], imageTimes, time_t, max);
- images = NX_ZONEREALLOC([self zone], images, NXImage *, max);
- }
- }
- imageNames[i]=NXCopyStringBufferFromZone(aName, [self zone]);
- images[i] = nil;
- }
- return i;
- }
-
- - setImage:(int)i
- {
- struct stat sb;
- char *p;
- int flag;
-
- if (i>=0 && i<imageCount) {
- if (imageNames[i][0]=='*') p=imageNames[i]+1; else p=imageNames[i];
- flag = stat(p, &sb);
- if (!images[i] || (flag==0 && imageTimes[i]<sb.st_mtime)) {
- images[i]=[[NXImage allocFromZone:[self zone]] initFromFile:p];
- imageTimes[i]=sb.st_mtime;
- if (imageNames[i][0]=='*') [self resizeImage:i];
- }
- current = i;
- }
- [self updateMenu];
- [self display];
- return self;
- }
-
- - resizeImage:(int)i
- {
- const NXScreen *screen;
- NXSize size;
-
- if (i>=0 && i<imageCount && images[i]) {
- screen = [window screen];
- size = screen->screenBounds.size;
- [images[i] setScalable:YES];
- [images[i] setSize:&size];
- }
- return self;
- }
-
- //
- // read and write defaults
- //
- - readDefault
- {
- char p[256], f[256];
- NXStream *s;
- FILE *temp;
- int ret;
-
- // pictures==NXReadDefault( "Background", "Image");
- if (s=NXMapFile(defaultfile, NX_READONLY)) {
- while (NXScanf(s, " %255[^ \n=]%1[ \n]", p, f)==2) [self loadImageNamed:p];
- ret = 1;
- while (ret && (ret=NXScanf(s," = \"%255[^\n\"]\" ", f))!=EOF) {
- // printf("Default read: %s = %s.\n", p, f);
- if (strncmp(p, "rep", 3)==0) [self setRepeatValue:atof(f)];
- else printf("Illegal default in %s: %s=%s.\n", defaultfile, p, f);
- ret=NXScanf(s," %255[^=\n] ", p);
- }
- NXCloseMemory(s, NX_FREEBUFFER);
- [self setImage:0];
- } else {
- fprintf(stderr, "Could not read from %s - creating it.\n", defaultfile);
- temp = fopen(defaultfile, "w");
- fclose(temp);
- }
- return self;
- }
-
- - writeDefault
- {
- int i;
- NXStream *s;
-
- s = NXOpenMemory(NULL, 0, NX_WRITEONLY) ;
- for (i=0; i<imageCount; i++) NXPrintf(s,"%s ",imageNames[i]);
- NXPrintf(s, " \nrepeat=\"%g\"\n", repeat);
- if (NXSaveToFile(s, defaultfile)<0) {
- printf("Could not write to %s.\n", defaultfile);
- exit(1);
- }
- NXCloseMemory(s, NX_FREEBUFFER);
- // NXWriteDefault( "Background", "Image", p); // Crashes default database
- return self;
- }
-
- //
- - mouseDown:(NXEvent *)event
- {
- PSsetwindowlevel( -1, [window windowNum]);
- [window orderWindow:NX_ABOVE relativeTo:0];
- [window removeFromEventMask:NX_MOUSEDOWNMASK];
- return self;
- }
-
- - (BOOL)acceptsFirstMouse
- {
- return YES;
- }
-
- - drawSelf:(NXRect *)r :(int)count
- {
- PSsetgray( NX_DKGRAY);
- NXRectFill( &bounds);
- if (permanent) { printf("Making permanent.\n"); PSputback(); }
- if(imageCount) {
- int i;
- NXSize s;
- NXSize screenSize;
- NXPoint p={ 0, 0};
- NXRect r={ p};
-
- [NXApp getScreenSize:&screenSize];
- [images[current] getSize:&s];
- r.size=s;
- // printf("Drawing image %s: [%g,%g].\n",imageNames[current],s.width,s.height);
- if (s.width>0 && s.height>0) {
- [images[current] composite:NX_COPY toPoint:&p];
- for( i=s.width; i<screenSize.width; i+=s.width) {
- p.x=i;
- PSsplat( &r, &p);
- }
- p.x=0;
- r.size.width=screenSize.width;
- for( i=s.height; i<screenSize.height; i+=s.height) {
- p.y=i;
- PSsplat( &r, &p);
- }
- }
- }
- return self;
- }
- //
- - windowDidBecomeKey:sender
- {
- PSsetwindowlevel( NX_DOCKLEVEL+1, [sender windowNum]);
- return self;
- }
-
- @end
-